/* 
 * File:   GLColor.h
 * Author: RedEyedKiller
 *
 * Created on 23 Ιούλιος 2011, 4:45 πμ
 */

#ifndef GLCOLOR_H
#define	GLCOLOR_H

#include <SDL/SDL_opengl.h>

#ifdef __GNUC__
#include <string.h>
#endif

namespace gl
{

/**
 * A simple class to represent a color in opengl.
 */

class Color
{
public:

    Color()
    {

    }

    Color(GLubyte r, GLubyte g, GLubyte b, GLubyte a = 255)
    {
        rgba[0] = r;
        rgba[1] = g;
        rgba[2] = b;
        rgba[3] = a;
    }

    Color(const Color& org)
    {
        memcpy(rgba, org.rgba, 4 * sizeof (GLubyte));
    }

    Color& operator =(const Color& org)
    {
        memcpy(rgba, org.rgba, 4 * sizeof (GLubyte));
        return *this;
    }

    const Color operator +(const Color& org) const
    {
        int r, g, b, a;

        r = this->Red() + org.Red();
        if (r > 255) r = 255;

        g = this->Green() + org.Green();
        if (g > 255) g = 255;

        b = this->Blue() + org.Blue();
        if (b > 255) b = 255;

        a = this->Alpha() + org.Alpha();
        if (a > 255) a = 255;

        return Color(r, g, b, a);
    }

    const Color operator -(const Color& org) const
    {
        int r, g, b, a;

        r = this->Red() - org.Red();
        if (r < 0) r = 0;

        g = this->Green() - org.Green();
        if (g < 0) g = 0;

        b = this->Blue() - org.Blue();
        if (b < 0) b = 0;

        a = this->Alpha() - org.Alpha();
        if (a < 0) a = 0;

        return Color(r, g, b, a);
    }

    const Color operator *(float value) const
    {
        int r, g, b, a;

        r = this->Red() * value;
        if (r > 255)
            r = 255;
        else if (r < 0)
            r = 0;

        g = this->Green() * value;
        if (g > 255)
            g = 255;
        else if (g < 0)
            g = 0;

        b = this->Blue() * value;
        if (b > 255)
            b = 255;
        else if (b < 0)
            b = 0;

        a = this->Alpha() * value;
        if (a > 255)
            a = 255;
        else if (a < 0)
            a = 0;

        return Color(r, g, b, a);
    }

    const Color operator /(float value) const
    {
        int r, g, b, a;

        r = this->Red() / value;
        if (r > 255)
            r = 255;
        else if (r < 0)
            r = 0;

        g = this->Green() / value;
        if (g > 255)
            g = 255;
        else if (g < 0)
            g = 0;

        b = this->Blue() / value;
        if (b > 255)
            b = 255;
        else if (b < 0)
            b = 0;

        a = this->Alpha() / value;
        if (a > 255)
            a = 255;
        else if (a < 0)
            a = 0;

        return Color(r, g, b, a);
    }

    ~Color()
    {

    }

    /**
     * Via this method you can apply this color into the opengl state.
     */
    inline void Apply()const
    {
        glColor4ubv(rgba);
    }

    /*Setters*/
    inline void SetRed(GLubyte r)
    {
        rgba[0] = r;
    }

    inline void SetGreen(GLubyte g)
    {
        rgba[1] = g;
    }

    inline void SetBlue(GLubyte b)
    {
        rgba[2] = b;
    }

    inline void SetAlpha(GLubyte a)
    {
        rgba[3] = a;
    }

    /*Getters*/
    inline GLubyte Red()const
    {
        return rgba[0];
    }

    inline GLubyte Green()const
    {
        return rgba[1];
    }

    inline GLubyte Blue()const
    {
        return rgba[2];
    }

    inline GLubyte Alpha()const
    {
        return rgba[3];
    }

private:
    /**
     * The four channels of color.
     */
    GLubyte rgba[4];
};

namespace colors
{
const Color RED(255, 0, 0);
const Color GREEN(0, 255, 0);
const Color BLUE(0, 0, 255);
const Color YELLOW(255, 255, 0);
const Color MANGETA(255, 0, 255);
const Color CYAN(0, 255, 255);
const Color WHITE(255, 255, 255);
const Color GRAY(128, 128, 128);
const Color BLACK(0, 0, 0);
}

}


#endif	/* GLCOLOR_H */

